#include <stddef.h>
#include <stdint.h>
#include <stdio.h>

#define NIT_SHORT_NAMES
#include <nit/list.h>
#include <nit/hset.h>
#include <nit/hmap.h>
#include <nit/radix.h>
#include <nit/vec.h>

#define ANO_SHORT_NAMES
#include "../ano.h"

#include "munit/munit.h"

static MunitResult
test_ano(const MunitParameter params[], void *data)
{
	int i = 0;
	Nit_radix radix;
	Ano_ano ano;
	Ano_tscan scan;
	char str[] = "nonpretypical cats typical catsically joke";
	Ano_bin *bin;
	Ano_form *form;

	radix_init(&radix, NULL);
	radix_insert(&radix, "non",        3,  "hello");
	radix_insert(&radix, "pre",        3,  ",");
	radix_insert(&radix, "typical",    7,  " ");
	radix_insert(&radix, "cats",       4,  "world");
	radix_insert(&radix, "catsically", 10, "!");
	radix_insert(&radix, "joke",       4,  "\n");

	ano_init(&ano, 0);
	tscan_init(&scan, &radix);

	for (; i < sizeof(str); ++i)
	        tscan_scan_unit(&scan, &ano, NULL, str + i, 1);

#define INC_FORM_VAL ((form = LIST_INC(bin)->forms)->val)

	bin = ano.bins;
	form = bin->forms;
	munit_assert_string_equal(form->val, "hello");
	munit_assert_string_equal(INC_FORM_VAL, ",");
	munit_assert_string_equal(INC_FORM_VAL, " ");
	munit_assert_string_equal(INC_FORM_VAL, "world");
	munit_assert_string_equal(INC_FORM_VAL, " ");
	munit_assert_string_equal(INC_FORM_VAL, "!");
	munit_assert_string_equal(LIST_INC(form)->val, "world");
	munit_assert_string_equal(INC_FORM_VAL, "\n");
}

static MunitTest test_suite_tests[] = {
	{ (char *) "/ano", test_ano,
	  NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL },
	{ NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL }

};

static const MunitSuite test_suite = {
	(char*) "ano",
	test_suite_tests,
	NULL,
	1,
	MUNIT_SUITE_OPTION_NONE
};

int
main(int argc, char *argv[])
{
	return munit_suite_main(&test_suite, NULL, argc, argv);
}
